package ms.unicorn.dsl.utils;

import ms.unicorn.Diagram;
import ms.unicorn.Element;
import ms.unicorn.dsl.analysis.IAnalysis;
import ms.unicorn.dsl.analysis.UnicornService;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;

public abstract class AbstractAnalysisHandler extends AbstractHandler implements IHandler {

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		ISelection selection = HandlerUtil.getCurrentSelection(event);
		
		if (selection instanceof StructuredSelection) {
			Object selObject = ((StructuredSelection) selection).getFirstElement();
			while (!(selObject instanceof DiagramEditPart) && selObject != null) selObject =  ((EditPart) selObject).getParent();
			Object model = ((GraphicalEditPart) selObject).getModel();
			if (model instanceof View) {
				View v = (View) model;
				EObject e =  v.getElement();
				
				while (!(e instanceof Diagram) && e != null) e = e.eContainer();
				
				if (e != null) {
					Diagram diagram = (Diagram) e;
						
					IAnalysis analysis = UnicornService.getAnalysisRegistryService().getAnalysis(getAnalysisType(), diagram);
					
					if (analysis == null) {
						analysis = createAnalysis(diagram);
						analysis.runAnalysis();
						UnicornService.getAnalysisRegistryService().registerAnalysis(analysis);
					}
					else {
						analysis.runAnalysis();
					}
					analysis.showAnalysisResult();
				}
			}
		}
		return null;
	}
	
	public abstract Class<? extends IAnalysis> getAnalysisType();
	
	public abstract IAnalysis createAnalysis(Element rootElement);
}